package com.example.openglesex;

import java.nio.ByteBuffer;
import java.nio.ByteOrder;
import java.nio.FloatBuffer;

import javax.microedition.khronos.opengles.GL10;

import android.util.Log;

public class CubeDrawAr {
	
	public static final int FACE_X = 0;
	public static final int FACE_Y = 1;
	public static final int FACE_Z = 2;
	
	public static final boolean DRAW_ARRAYS = true;
	public static final boolean DRAW_ELEMENTS = false;
	public static final int CUBE_FINAL = 6;
	
	private float[] mIntersection = new float[3];
	
	private int mSelected = -1 ;  //选中了哪个面 -1表示没有选中任何面
	private float[][] mCoords;
	private float[][] mColor;
	
	private float mSize;
	public int[] mTextures;
	
	private static float[][] mTexCoord = new float[][] {
		new float[] { // top
			1, 0,
			1, 1,
			0, 1,
			0, 0
		},
		new float[] { // bottom
			0, 0,
			1, 0,
			1, 1,
			0, 1
		},
		new float[] { // front
			1, 1,
			0, 1,
			0, 0,
			1, 0
		},
		new float[] { // back
			0, 1,
			0, 0,
			1, 0,
			1, 1
		},
		new float[] { // left
			1, 1,
			0, 1,
			0, 0,
			1, 0
		},
		new float[] { // right
			0, 1,
			0, 0,
			1, 0,
			1, 1
		},
	};
	
	private FloatBuffer[] mTexCoordBuffer;
	private FloatBuffer[] mColorBuffer;
	private FloatBuffer[] mVertexBuffer;
	public CubeDrawAr(float size) {
		this.mSize = size;
		initCoords();
		initColor();
		
		mTexCoordBuffer = new FloatBuffer[CUBE_FINAL];
		for(int i=0;i<CUBE_FINAL;i++){
			ByteBuffer tbb = ByteBuffer.allocateDirect(mTexCoord[i].length * 4);
			tbb.order(ByteOrder.nativeOrder());
			mTexCoordBuffer[i] = tbb.asFloatBuffer();
			mTexCoordBuffer[i].put(mTexCoord[i]);
			mTexCoordBuffer[i].position(0);
		}
	}
		
	private void initColor() {
		mColor = new float[CUBE_FINAL][];
		mColorBuffer = new FloatBuffer[CUBE_FINAL];
		for(int i=0;i<CUBE_FINAL;i++){
			mColor[i] = new float[]{
					(float)Math.random(),(float)Math.random(),(float)Math.random(),1,
					(float)Math.random(),(float)Math.random(),(float)Math.random(),1,
					(float)Math.random(),(float)Math.random(),(float)Math.random(),1,
					(float)Math.random(),(float)Math.random(),(float)Math.random(),1
			};
			mColorBuffer[i] = getOrderBB(mColor[i].length * 4).asFloatBuffer();
			mColorBuffer[i].put(mColor[i]);
			mColorBuffer[i].position(0);
			
		}
		
	}

	private void initCoords(){
		mCoords = new float[][] {
				new float[] { // top
					 mSize, mSize,-mSize,
					-mSize, mSize,-mSize,
					-mSize, mSize, mSize,
					 mSize, mSize, mSize
				},
				new float[] { // bottom
					 mSize,-mSize, mSize,
					-mSize,-mSize, mSize,
					-mSize,-mSize,-mSize,
					 mSize,-mSize,-mSize
				},
				new float[] { // front
					 mSize, mSize, mSize,
					-mSize, mSize, mSize,
					-mSize,-mSize, mSize,
					 mSize,-mSize, mSize
				},
				new float[] { // back
					 mSize,-mSize,-mSize,
					-mSize,-mSize,-mSize,
					-mSize, mSize,-mSize,
					 mSize, mSize,-mSize
				},
				new float[] { // left
					-mSize, mSize, mSize,
					-mSize, mSize,-mSize,
					-mSize,-mSize,-mSize,
					-mSize,-mSize, mSize
				},
				new float[] { // right
					 mSize, mSize,-mSize,
					 mSize, mSize, mSize,
					 mSize,-mSize, mSize,
					 mSize,-mSize,-mSize
				}
			};
		mVertexBuffer = new FloatBuffer[CUBE_FINAL];
		for (int i = 0; i < CUBE_FINAL; i++)
		{
			mVertexBuffer[i] = getOrderBB(mCoords[i].length * 4).asFloatBuffer();
			mVertexBuffer[i].put(mCoords[i]);
			mVertexBuffer[i].position(0);
		}
	}
	
	public void draw(GL10 gl){
		for (int i = 0; i < CUBE_FINAL; i++){
			if(i == mSelected){
				gl.glDisable(GL10.GL_TEXTURE_2D);
				gl.glColor4f(1, 0, 0, 1);
				gl.glVertexPointer(3, GL10.GL_FLOAT, 0, mVertexBuffer[i]);
				gl.glDrawArrays(GL10.GL_TRIANGLE_FAN, 0, 4);
				gl.glDisable(GL10.GL_BLEND);
				gl.glColor4f(1, 1, 1, 1);
				gl.glEnable(GL10.GL_TEXTURE_2D);
			}else{
				gl.glBindTexture(GL10.GL_TEXTURE_2D,mTextures[i]);
				gl.glTexCoordPointer(2, GL10.GL_FLOAT, 0, mTexCoordBuffer[i]);
				gl.glVertexPointer(3, GL10.GL_FLOAT, 0, mVertexBuffer[i]);
				//gl.glColorPointer(4, GL10.GL_FLOAT, 0, mColorBuffer[i]);
				gl.glDrawArrays(GL10.GL_TRIANGLE_FAN, 0, 4);
				gl.glDisable(GL10.GL_BLEND);
				gl.glColor4f(1, 1, 1, 1);
			}
		}
		
	}
	
	private ByteBuffer getOrderBB(int capacity){
		ByteBuffer bb = ByteBuffer.allocateDirect(capacity);
		bb.order(ByteOrder.nativeOrder());
		return bb;
	}
	
	/**
	 * 功能简述:计算射线与立方体面的相交距离射线原点的距离的平方
	 * 功能详细描述:
	 * 注意:
	 * @param origin
	 * @param direction
	 * @param face  取 FACE_X, FACE_Y,  FACE_Z  中的一个
	 * @param value 取1或-1    face 和  value 共同决定了正六个面的其中之一 
	 * @return  平行或无交点返回Float.MAX_VALUE
	 */
	public float intersect(float[] origin, float[] direction, int face, float value){		
		mIntersection[face] = value;
		float e;
		//将x = 1代入直接方程
		if(direction[0] - origin[0] == 0){
			//Log.i("----", "平行");
			return Float.MAX_VALUE;
		}
		e = (mIntersection[face] - origin[face])/(direction[face] - origin[face]);
		
		mIntersection[0] = e * (direction[0] - origin[0]) + origin[0];
		mIntersection[1] = e * (direction[1] - origin[1]) + origin[1];
		mIntersection[2] = e * (direction[2] - origin[2]) + origin[2];
		
		if(     mIntersection[0] <= 1 && mIntersection[0] >= -1 &&
				mIntersection[1] <= 1 && mIntersection[1] >= -1 &&
				mIntersection[2] <= 1 && mIntersection[2] >= -1   ){
			
			return (mIntersection[0] - origin[0]) * (mIntersection[0] - origin[0]) + 
				   (mIntersection[1] - origin[1]) * (mIntersection[1] - origin[1]) +
				   (mIntersection[2] - origin[2]) * (mIntersection[2] - origin[2]) ;
			//Log.i("----", "in:"+face+","+value); 
		}
		//Log.i("----", mIntersection[0]+","+mIntersection[1]+","+mIntersection[2]);
		return Float.MAX_VALUE;
	}
	
	public void intersect(float[] origin, float[] direction){
		float temp;
		float min  = Float.MAX_VALUE;
		mSelected = -1;
		//top面，Y = 1
		if((temp = intersect(origin, direction, FACE_Y,  1)) < min ){
			mSelected = 0;
			min = temp;
		}
		//bottom面，Y = -1
		if((temp = intersect(origin, direction, FACE_Y, -1)) < min){
			min = temp;
			mSelected = 1;
		}
		//front面，Z = 1
		if((temp = intersect(origin, direction, FACE_Z,  1)) < min){
			min = temp;
			mSelected = 2;
		}
		//back面，Z = -1
		if((temp = intersect(origin, direction, FACE_Z, -1)) < min){
			min = temp;
			mSelected = 3;
		}
		//left面，X = -1
		if((temp = intersect(origin, direction, FACE_X, -1)) < min){
			min = temp;
			mSelected = 4;
		}
		//right面， X = 1
		if((temp = intersect(origin, direction, FACE_X,  1)) < min){
			min = temp;
			mSelected = 5;
		}
	}
}
